//===============================================================================
// Microsoft patterns & practices
// Web Client Software Factory
//-------------------------------------------------------------------------------
// Copyright (C) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//-------------------------------------------------------------------------------
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================
using System;
using WCSFContrib.PageFlow.Configuration;
using WCSFContrib.PageFlow.WorkflowFoundation.Tests.Mocks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WCSFContrib.PageFlow.Tests.Mocks;

namespace WCSFContrib.PageFlow.WorkflowFoundation.Tests
{
	[TestClass]
	public class WorkflowFoundationPageFlowProviderFixture
	{
        [ClassInitialize]
        public static void SetupDatabase(TestContext testContext)
        {
            SetupDatabaseUtility.Setup();
        }

		[TestMethod]
		public void CanCreateNew()
		{
			IPageFlowProvider provider =
				new WorkflowFoundationPageFlowProvider(new MockPageFlowFactory(),
				                                       new MockPageFlowInstanceStore(string.Empty));

			Assert.IsNotNull(provider);
			Assert.IsTrue(provider is WorkflowFoundationPageFlowProvider);
		}

		[TestMethod]
		public void CanCreateNewUsingConfigurationSection()
		{
			string storeType =
                string.Format("{0}, {1}", typeof(MockPageFlowInstanceStoreWithTokenProvider), typeof(MockPageFlowInstanceStoreWithTokenProvider).Assembly.FullName);
            string tokenProviderType =
                string.Format("{0}, {1}", typeof(MockPageFlowCorrelationTokenProvider), typeof(MockPageFlowCorrelationTokenProvider).Assembly.FullName);
            PageFlowInstanceStoreProviderSection storeSection = new PageFlowInstanceStoreProviderSection(storeType, null);
            PageFlowInstanceCorrelationTokenProviderSection tokenSection = new PageFlowInstanceCorrelationTokenProviderSection(tokenProviderType);
            
            IPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(storeSection, tokenSection);

			Assert.IsNotNull(provider);
			Assert.IsTrue(provider is WorkflowFoundationPageFlowProvider);
		}

		[TestMethod]
		[ExpectedException(typeof (ArgumentNullException))]
		public void PageFlowInstanceStoreProviderCannotBeNull()
		{
            new WorkflowFoundationPageFlowProvider(null, new PageFlowInstanceCorrelationTokenProviderSection());
		}

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void PageFlowInstanceCorrelationTokenProviderCannotBeNull()
        {
            new WorkflowFoundationPageFlowProvider(new PageFlowInstanceStoreProviderSection(), null);
        }
		
		[TestMethod]
		public void ShouldReturnInstanceFromStoreIfItExists()
		{
			IPageFlowFactory factory = new WorkflowFoundationPageFlowFactory(new MockNavigationService());
			IPageFlow flow = factory.GetPageFlow(typeof (MockConstrainedPageFlow));
			IPageFlowInstanceStore store = new MockPageFlowInstanceStore(string.Empty);
			store.Add(flow);
			using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
			{
				IPageFlow pageFlow = provider.GetPageFlow(typeof(MockConstrainedPageFlow));
				
				Assert.AreEqual(flow.Id, pageFlow.Id);
			}
		}
		
		[TestMethod]
		public void ShouldReturnNewInstanceIfItIsntAvailableOnStoreAndSaveInstanceOnStore()
		{
			IPageFlowFactory factory = new WorkflowFoundationPageFlowFactory(new MockNavigationService());
			MockPageFlowInstanceStore store = new MockPageFlowInstanceStore(null);
			
			using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
			{
				IPageFlow pageFlow = provider.GetPageFlow(typeof(MockConstrainedPageFlow));
				
				Assert.IsNotNull(pageFlow);
				Assert.IsTrue(store.ContainsKey(typeof(MockConstrainedPageFlow)));
				Assert.AreSame(store[typeof(MockConstrainedPageFlow)], pageFlow);
			}
		}
		
		[TestMethod]
		public void ShouldGetInstanceById()
		{

			IPageFlowFactory factory = new WorkflowFoundationPageFlowFactory(new MockNavigationService());
			IPageFlow flow = factory.GetPageFlow(typeof (MockConstrainedPageFlow));
            flow.Start();
            flow.Suspend();
			MockPageFlowInstanceStore store = new MockPageFlowInstanceStore(null);
            store.Add(flow);

			using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
			{
				IPageFlow pageFlow = provider.GetPageFlow(flow.Id);

				Assert.AreEqual(flow.Id, pageFlow.Id);
			}
		}

        [TestMethod]
        [ExpectedException(typeof(PageFlowException))]
        public void ShouldThrowIfGetInstanceByIdAndInstanceNotFoundInStore()
        {

            IPageFlowFactory factory = new WorkflowFoundationPageFlowFactory(new MockNavigationService());
            IPageFlow flow = factory.GetPageFlow(typeof(MockConstrainedPageFlow));
            MockPageFlowInstanceStore store = new MockPageFlowInstanceStore(null);

            using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
            {
                IPageFlow pageFlow = provider.GetPageFlow(flow.Id);
            }
        }
		
		[TestMethod]
		public void ShouldRemoveFlowFromStoreWhenOnPageFlowAborted()
		{
			IPageFlowFactory factory = new WorkflowFoundationPageFlowFactory(new MockNavigationService());
			MockPageFlowInstanceStore store = new MockPageFlowInstanceStore(null);

			using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
			{
				IPageFlow pageFlow = provider.GetPageFlow(typeof(MockUnconstrainedPageFlow));
				pageFlow.Start();
				
				pageFlow.Abort(false);
				
				Assert.AreEqual(Guid.Empty, store.GetLastRunningInstance());
				Assert.IsFalse(store.ContainsKey(typeof(MockUnconstrainedPageFlow)));

			}	
		}

		[TestMethod]
		public void ShouldSetInstanceAsRunningWhenStarted()
		{
			IPageFlowFactory factory = new WorkflowFoundationPageFlowFactory(new MockNavigationService());
			MockPageFlowInstanceStore store = new MockPageFlowInstanceStore(null);

			using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
			{
				IPageFlow pageFlow = provider.GetPageFlow(typeof(MockUnconstrainedPageFlow));
				pageFlow.Start();

				Assert.IsNotNull(store.GetLastRunningInstance());
				Assert.AreEqual(store.GetLastRunningInstance(), pageFlow.Id);
				Assert.IsTrue(store.ContainsKey(typeof(MockUnconstrainedPageFlow)));
			}
		}

		[TestMethod]
		public void ShouldRemoveInstanceFromStoreWhenCompleted()
		{
			IPageFlowFactory factory = new WorkflowFoundationPageFlowFactory(new MockNavigationService());
			MockPageFlowInstanceStore store = new MockPageFlowInstanceStore(null);

			using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
			{
				IPageFlow pageFlow = provider.GetPageFlow(typeof(MockUnconstrainedPageFlow));
				pageFlow.Start();
				pageFlow.Complete();
				
				Assert.AreEqual(Guid.Empty, store.GetLastRunningInstance());
				Assert.IsFalse(store.ContainsKey(typeof(MockUnconstrainedPageFlow)));
			}
		}
		
		[TestMethod]
		public void ShouldMarkInstanceAsNotRunningAndKeepItOnStoreWhenSuspended()
		{
			IPageFlowFactory factory = new WorkflowFoundationPageFlowFactory(new MockNavigationService());
			MockPageFlowInstanceStore store = new MockPageFlowInstanceStore(null);

			using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
			{
				IPageFlow pageFlow = provider.GetPageFlow(typeof(MockUnconstrainedPageFlow));
				pageFlow.Start();
				pageFlow.Suspend();

				Assert.AreEqual(Guid.Empty, store.GetLastRunningInstance());
				Assert.IsTrue(store.ContainsKey(typeof(MockUnconstrainedPageFlow)));
			}
		}

		[TestMethod]
		public void ProcessRequestShouldRedirectConstrainedPageFlow()
		{
            MockPageFlowFactory factory = new MockPageFlowFactory();
			MockPageFlowInstanceStore store = new MockPageFlowInstanceStore(null);

			IPageFlowDefinitionCatalog catalog = new PageFlowDefinitionCatalog();
			IPageFlowDefinition definition = new WCSFContrib.PageFlow.Tests.Mocks.MockConstrainedPageFlowDefinition();
			catalog.Add(definition);

			MockPageFlow pageFlowInstance = new MockPageFlow(definition);
            factory.AddPageFlow(typeof(MockPageFlow), pageFlowInstance );
			store.Add(pageFlowInstance);
			Page currentPage = new Page("PageC", "~/pageC.aspx");
			pageFlowInstance.CurrentPage = currentPage;
			store.SetPageFlowRunning(pageFlowInstance);
			
			using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
			{
				ProcessResult result = provider.ProcessRequest("~/pageA.aspx");
			
				Assert.IsTrue(result.ShouldRedirect);
				Assert.AreEqual("~/pageC.aspx", result.RedirectUrl);
				Assert.AreEqual(currentPage, pageFlowInstance.CurrentPage);
			}
		}

		[TestMethod]
		public void PageFlowAbandonedEventCallsAbort()
		{
            MockPageFlowFactory factory = new MockPageFlowFactory();

			IPageFlowDefinitionCatalog catalog = new PageFlowDefinitionCatalog();
			MockConstrainedPageFlowDefinition definition = new MockConstrainedPageFlowDefinition();
			definition.Abandonable = AbandonBehavior.AllowAndDiscardInstance;
			catalog.Add(definition);

			MockPageFlowInstanceStore store = new MockPageFlowInstanceStore(null);

			MockPageFlow pageFlowInstance = new MockPageFlow(definition);
            factory.AddPageFlow(typeof(MockPageFlow), pageFlowInstance);
			store.Add(pageFlowInstance);
			Page currentPage = new Page("PageC", "~/pageC.aspx");
			pageFlowInstance.CurrentPage = currentPage;

			store.SetPageFlowRunning(pageFlowInstance);

			using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
			{
				ProcessResult result = provider.ProcessRequest("http://localhost/outsidePageFlowPage.aspx");
			}

			Assert.IsTrue(pageFlowInstance.AbortCalled);            

		}

		[TestMethod]
		public void ShouldRedirectToCurrentPageWhenRequestingNonPageFlowPageAndPageFlowIsNotAbandonable()
		{
            MockPageFlowFactory factory = new MockPageFlowFactory();

			IPageFlowDefinitionCatalog catalog = new PageFlowDefinitionCatalog();
			MockConstrainedPageFlowDefinition definition = new MockConstrainedPageFlowDefinition();
			definition.Abandonable = AbandonBehavior.Prevent;
			catalog.Add(definition);

			MockPageFlowInstanceStore store = new MockPageFlowInstanceStore(null);

			MockPageFlow pageFlowInstance = new MockPageFlow(definition);
            factory.AddPageFlow(typeof(MockPageFlow), pageFlowInstance);
			store.Add(pageFlowInstance);
			Page currentPage = new Page("PageC", "~/pageC.aspx");
			pageFlowInstance.CurrentPage = currentPage;
			store.SetPageFlowRunning(pageFlowInstance);

			using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
			{				
				ProcessResult result = provider.ProcessRequest("http://localhost/outsidePageFlowPage.aspx");
				Assert.IsTrue(result.ShouldRedirect);
				Assert.AreEqual(currentPage.Url, result.RedirectUrl);
			}

		}

        [TestMethod]
        public void ShouldSuspendWhenRequestingNonPageFlowPageAndPageFlowIsAbandonableReusable()
        {
            MockPageFlowFactory factory = new MockPageFlowFactory();

            IPageFlowDefinitionCatalog catalog = new PageFlowDefinitionCatalog();
            MockConstrainedPageFlowDefinition definition = new MockConstrainedPageFlowDefinition();
            definition.Abandonable = AbandonBehavior.AllowAndSaveInstance;
            catalog.Add(definition);

            MockPageFlowInstanceStore store = new MockPageFlowInstanceStore(null);

            MockPageFlow pageFlowInstance = new MockPageFlow(definition);
            factory.AddPageFlow(typeof(MockPageFlow), pageFlowInstance);
            store.Add(pageFlowInstance);
            Page currentPage = new Page("PageC", "~/pageC.aspx");
            pageFlowInstance.CurrentPage = currentPage;
            store.SetPageFlowRunning(pageFlowInstance);

            using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
            {
                ProcessResult result = provider.ProcessRequest("http://localhost/outsidePageFlowPage.aspx");
                Assert.IsFalse(result.ShouldRedirect);
            }

            Assert.IsTrue(pageFlowInstance.SuspendCalled);
        }

        [TestMethod]
        public void ShouldResumeOnCurrentPageWhenRequestingPageFlowPageAndPageFlowIsAbandonableReusable()
        {
            MockPageFlowFactory factory = new MockPageFlowFactory();

            MockConstrainedPageFlowDefinition definition = new MockConstrainedPageFlowDefinition();
            definition.Abandonable = AbandonBehavior.AllowAndSaveInstance;
            PageFlowDirectory.Catalog.Add(definition);

            MockPageFlowInstanceStore store = new MockPageFlowInstanceStore(null);

            MockPageFlow pageFlowInstance = new MockPageFlow(definition);
            factory.AddPageFlow(typeof(MockPageFlow), pageFlowInstance);
            store.Add(pageFlowInstance);
            Page currentPage = new Page("PageC", "~/pageC.aspx");
            pageFlowInstance.CurrentPage = currentPage;
            store.SetPageFlowRunning(pageFlowInstance);

            using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
            {
                ProcessResult result1 = provider.ProcessRequest("~/outsidePageFlowPage.aspx");
                Assert.AreEqual(PageFlowStatus.Suspended, pageFlowInstance.Status);

                ProcessResult result2 = provider.ProcessRequest("~/pageA.aspx");
                Assert.IsFalse(result2.ShouldRedirect);
				Assert.AreEqual(currentPage.Url, pageFlowInstance.CurrentPage.Url);
                Assert.AreEqual(PageFlowStatus.Running, pageFlowInstance.Status);
            }

            PageFlowDirectory.Catalog.Remove(definition);
        }

        [TestMethod]
		public void ShouldRedirectUserToNotStartedPageWhenRequestingPageFlowPageAndPageFlowNotStarted()
		{
            MockPageFlowFactory factory = new MockPageFlowFactory();

			MockConstrainedPageFlowDefinition definition = new MockConstrainedPageFlowDefinition();
			definition.Abandonable = AbandonBehavior.Prevent;
            PageFlowDirectory.Catalog.Add(definition);

			MockPageFlowInstanceStore store = new MockPageFlowInstanceStore(null);

			using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
			{
				ProcessResult result = provider.ProcessRequest("~/pageA.aspx");
				Assert.IsTrue(result.ShouldRedirect);
				Assert.AreEqual(definition.NotRunningRedirect, result.RedirectUrl);

			}

            PageFlowDirectory.Catalog.Remove(definition);
		}

        [TestMethod]
        public void ShouldResumePageFlow2WhenJumpingFromPageFlow1AndSuspendPageFlow1()
        {
            MockPageFlowFactory factory = new MockPageFlowFactory();
            MockPageFlowInstanceStore store = new MockPageFlowInstanceStore(null);

            MockConfigurablePageFlowDefinition definition1 = CreatePageFlowDef1();
            PageFlowDirectory.Catalog.Add(definition1);
            MockConfigurablePageFlowDefinition definition2 = CreatePageFlowDef2();
            PageFlowDirectory.Catalog.Add(definition2);
            
            MockPageFlow pageFlowInstance1 = new MockPageFlow(definition1);
            pageFlowInstance1.CurrentPage = new Page("A", "~/a.aspx");

            MockPageFlow pageFlowInstance2 = new MockPageFlow(definition2);
            pageFlowInstance2.CurrentPage = new Page("Z", "~/z.aspx");
            pageFlowInstance2.Suspend();

            factory.AddPageFlow(typeof(MockConstrainedPageFlow), pageFlowInstance1);
            factory.AddPageFlow(typeof(MockConstrainedPageFlow2), pageFlowInstance2);

            store.Add(pageFlowInstance1);
            store.Add(pageFlowInstance2);
            store.SetPageFlowRunning(pageFlowInstance1);

            using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
            {
                ProcessResult result = provider.ProcessRequest("~/z.aspx");
                Assert.AreEqual(PageFlowStatus.Suspended, pageFlowInstance1.Status);
                Assert.AreEqual(PageFlowStatus.Running, pageFlowInstance2.Status);

            }

            PageFlowDirectory.Catalog.Remove(definition1);
            PageFlowDirectory.Catalog.Remove(definition2);
        }

        [TestMethod]
        public void ShouldRedirectToNotStartedWhenJumpingFromPageFlow1ToANonStartedPageFlow2()
        {
            MockPageFlowFactory factory = new MockPageFlowFactory();
            MockPageFlowInstanceStore store = new MockPageFlowInstanceStore(null);

            MockConfigurablePageFlowDefinition definition1 = CreatePageFlowDef1();
            PageFlowDirectory.Catalog.Add(definition1);
            MockConfigurablePageFlowDefinition definition2 = CreatePageFlowDef2();
            PageFlowDirectory.Catalog.Add(definition2);

            MockPageFlow pageFlowInstance1 = new MockPageFlow(definition1);
            pageFlowInstance1.CurrentPage = new Page("A", "~/a.aspx");

            MockPageFlow pageFlowInstance2 = new MockPageFlow(definition2);

            factory.AddPageFlow(typeof(MockConstrainedPageFlow), pageFlowInstance1);
            factory.AddPageFlow(typeof(MockConstrainedPageFlow2), pageFlowInstance2);

            store.Add(pageFlowInstance1);
            store.SetPageFlowRunning(pageFlowInstance1);

            using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
            {
                ProcessResult result = provider.ProcessRequest("~/z.aspx");
                Assert.AreEqual(PageFlowStatus.Suspended, pageFlowInstance1.Status);
                Assert.AreEqual(PageFlowStatus.NotStarted, pageFlowInstance2.Status);
                Assert.IsTrue(result.ShouldRedirect);
                Assert.AreEqual(definition2.NotRunningRedirect, result.RedirectUrl);

            }

            PageFlowDirectory.Catalog.Remove(definition1);
            PageFlowDirectory.Catalog.Remove(definition2);
        }

        [TestMethod]
        public void ShouldRedirectToCurrentPageWhenJumpingFromPageFlow1ToARunningPageFlow2()
        {
            MockPageFlowFactory factory = new MockPageFlowFactory();
            MockPageFlowInstanceStore store = new MockPageFlowInstanceStore(null);

            MockConfigurablePageFlowDefinition definition1 = CreatePageFlowDef1();
            PageFlowDirectory.Catalog.Add(definition1);
            MockConfigurablePageFlowDefinition definition2 = CreatePageFlowDef2();
            PageFlowDirectory.Catalog.Add(definition2);

            MockPageFlow pageFlowInstance1 = new MockPageFlow(definition1);
            pageFlowInstance1.CurrentPage = new Page("A", "~/a.aspx");
            pageFlowInstance1.Start();

            MockPageFlow pageFlowInstance2 = new MockPageFlow(definition2);
            pageFlowInstance2.CurrentPage = new Page("X", "~/x.aspx");
            pageFlowInstance2.Start();

            factory.AddPageFlow(typeof(MockConstrainedPageFlow), pageFlowInstance1);
            factory.AddPageFlow(typeof(MockConstrainedPageFlow2), pageFlowInstance2);

            store.Add(pageFlowInstance1);
            store.Add(pageFlowInstance2);
            store.SetPageFlowRunning(pageFlowInstance1);
            store.SetPageFlowRunning(pageFlowInstance2);

            using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
            {
                ProcessResult result = provider.ProcessRequest("~/z.aspx");
                Assert.AreEqual(PageFlowStatus.Suspended, pageFlowInstance1.Status);
                Assert.AreEqual(PageFlowStatus.Running, pageFlowInstance2.Status);
                Assert.IsTrue(result.ShouldRedirect);
                Assert.AreEqual(pageFlowInstance2.CurrentPage.Url, result.RedirectUrl);

            }

            PageFlowDirectory.Catalog.Remove(definition1);
            PageFlowDirectory.Catalog.Remove(definition2);
        }



        
        private MockConfigurablePageFlowDefinition CreatePageFlowDef1()
        {
            MockConfigurablePageFlowDefinition definition1 = new MockConfigurablePageFlowDefinition();
            definition1.Abandonable = AbandonBehavior.AllowAndSaveInstance;
            definition1.Constrained = true;
            definition1.AddPage(new Page("A", "~/a.aspx"));
            definition1.AddPage(new Page("B", "~/b.aspx"));
            definition1.PageFlowType = typeof(MockConstrainedPageFlow);
            return definition1;
        }

        private MockConfigurablePageFlowDefinition CreatePageFlowDef2()
        {
            MockConfigurablePageFlowDefinition definition2 = new MockConfigurablePageFlowDefinition();
            definition2.Abandonable = AbandonBehavior.AllowAndSaveInstance;
            definition2.Constrained = true;
            definition2.AddPage(new Page("X", "~/x.aspx"));
            definition2.AddPage(new Page("Y", "~/y.aspx"));
            definition2.AddPage(new Page("Z", "~/z.aspx"));
            definition2.PageFlowType = typeof(MockConstrainedPageFlow2);
            return definition2;
        }

		[TestMethod]
		public void ShouldSetPageFlowStateWhenUnconstrainedPageFlowPageIsRequested()
		{
            MockPageFlowFactory factory = new MockPageFlowFactory();

			IPageFlowDefinitionCatalog catalog = new PageFlowDefinitionCatalog();
			MockUnconstrainedPageFlowDefinition definition = new MockUnconstrainedPageFlowDefinition();
			definition.Abandonable = AbandonBehavior.AllowAndDiscardInstance;
			catalog.Add(definition);

			IPageFlowInstanceStore store = new MockPageFlowInstanceStore(null);

			MockPageFlow pageFlowInstance = new MockPageFlow(definition);
            factory.AddPageFlow(typeof(MockPageFlow), pageFlowInstance);
			pageFlowInstance.CurrentPage = new Page("PageC", "~/pageC.aspx");
			store.Add(pageFlowInstance);

			store.SetPageFlowRunning(pageFlowInstance);

			using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
			{
				ProcessResult result = provider.ProcessRequest("~/pageA.aspx");

				Assert.IsFalse(result.ShouldRedirect);
				Assert.AreEqual("pageA", pageFlowInstance.CurrentPage.Name);
			}
			
		}

		[TestMethod]
		public void ShouldNotRedirectOnConstrainedPageFlowIfRequestingCurrentPage()
		{
            MockPageFlowFactory factory = new MockPageFlowFactory();

			IPageFlowDefinitionCatalog catalog = new PageFlowDefinitionCatalog();
			MockConstrainedPageFlowDefinition definition = new MockConstrainedPageFlowDefinition();
			catalog.Add(definition);

			IPageFlowInstanceStore store = new MockPageFlowInstanceStore(null);

			MockPageFlow pageFlowInstance = new MockPageFlow(definition);
            factory.AddPageFlow(typeof(MockPageFlow), pageFlowInstance);
			pageFlowInstance.CurrentPage = new Page("PageA", "~/pageA.aspx");
			store.Add(pageFlowInstance);
			store.SetPageFlowRunning(pageFlowInstance);

			using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
			{
				ProcessResult result = provider.ProcessRequest("~/pageA.aspx");
				Assert.IsFalse(result.ShouldRedirect);
			}
		}

        [TestMethod]
        public void ShouldMantainPageFlowStatusInDifferentRequestsWhenPageFlowIsNotStarted()
        {
            IPageFlowFactory factory = new WorkflowFoundationPageFlowFactory(new MockNavigationService());
            MockPageFlowInstanceStore store = new MockPageFlowInstanceStore(null);

            using (WorkflowFoundationPageFlowProvider provider = new WorkflowFoundationPageFlowProvider(factory, store))
            {
                IPageFlow pageFlow1 = provider.GetPageFlow(typeof(MockConstrainedPageFlow));
                Assert.AreEqual(PageFlowStatus.NotStarted, pageFlow1.Status);                
                
                IPageFlow pageFlow2 = provider.GetPageFlow(typeof(MockConstrainedPageFlow));
                Assert.AreEqual(PageFlowStatus.NotStarted, pageFlow2.Status);                                
            }
        }      
	}

    class MockPageFlowInstanceStoreWithTokenProvider : MockPageFlowInstanceStore
    {
        public MockPageFlowInstanceStoreWithTokenProvider(string connectionString, IPageFlowCorrelationTokenProvider token) : base(connectionString)
        {

        }
    }
}
